package dao

import (
	"context"
	"database/sql"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/go-sql-driver/mysql"
	"gorm.io/gorm"
	"time"
)

var (
	ErrDuplicateEmail = errors.New("用户名冲突")
	ErrRecordNotFound = gorm.ErrRecordNotFound
)

func NewUserDao(db *gorm.DB) *UserDao {
	return &UserDao{
		db: db,
	}
}

type UserDao struct {
	db *gorm.DB
}

type User struct {
	Id       int64          `gorm:"primaryKey,autoIncrement"`
	Email    sql.NullString `gorm:"unique"`
	Password string         `gorm:"column:password"`

	// 时区，UTC 0 的毫秒数
	// 创建时间
	Ctime    int64 `gorm:"column:ctime"`
	Utime    int64 `gorm:"column:utime"`
	Nickname string
	Birthday int64
	AboutMe  string
	//Addr     string `gorm:"column:addr"`
}

//type Address struct {
//	Uid
//}

func (dao *UserDao) Insert(ctx context.Context, u User) error {
	now := time.Now().UnixMilli()
	u.Ctime = now
	u.Utime = now
	err := dao.db.WithContext(ctx).Create(&u).Error
	if me, ok := err.(*mysql.MySQLError); ok {
		if me.Number == 1062 {
			//用户冲突，邮箱冲突
			return ErrDuplicateEmail
		}
	}
	return err
}

func (dao *UserDao) FindByEmail(ctx context.Context, email string) (User, error) {
	var u User
	err := dao.db.WithContext(ctx).Where("email = ?", email).First(&u).Error
	return u, err
}

func (dao *UserDao) UpdateUser(ctx context.Context, u User, uid int64) (User, error) {
	err := dao.db.WithContext(ctx).Update("id=?", uid).First(&u).Error
	if err != nil {
		return User{}, nil
	}
	return u, nil
}

func (dao *UserDao) UpdateById(ctx *gin.Context, entity User) error {
	return dao.db.WithContext(ctx).Model(&entity).Where("id=?", entity.Id).Updates(map[string]any{
		"utime":    time.Now().UnixMilli(),
		"nickname": entity.Nickname,
		"birthday": entity.Birthday,
		"about_me": entity.Password,
	}).Error
}

func (dao *UserDao) FindById(ctx *gin.Context, uid int64) (User, error) {
	var u User
	err := dao.db.WithContext(ctx).Where("id = ?", uid).First(&u).Error
	return u, err
}
